#define LOG_TAG "EffectCross"
#define LOG_NDEBUG 0
#include "log/log.h"
#include <math.h>
#include "tinyxml2.h"
#include "parse_xml_v2.h"

using namespace std;
using namespace tinyxml2;

// 解析单个 remix 节点
static bool parseRemixElement(XMLElement* remixElem, Remix& remix) {
    // 解析 <source> 元素
    for (XMLElement* sourceElem = remixElem->FirstChildElement("source");
         sourceElem;
         sourceElem = sourceElem->NextSiblingElement("source")) {
        float gain = sourceElem->FloatAttribute("gain", 0.0f);
        float factor = powf(10, gain / 20);
        remix.sources.push_back({
            sourceElem->IntAttribute("channel", -1),
            gain,
            factor
        });
    }

    // 解析 <target> 元素
    if (XMLElement* targetElem = remixElem->FirstChildElement("target")) {
        float gain = targetElem->FloatAttribute("gain", 0.0f);
        float factor = powf(10, gain / 20);
        remix.target = {
            targetElem->IntAttribute("channel", -1),
            gain,
            factor
        };
        return true;
    } else {
        ALOGE("Warning: remix element without target attribute skipped.");
        return false;
    }
}

bool parseXml(CrossEffectConfig* pConfig, const char* filename) {
    if (pConfig == NULL) {
        //cerr << "pConfig should NOT be NULL " << endl;
        return false;
    }

    XMLDocument doc;
    if (doc.LoadFile(filename) != XML_SUCCESS) {
        //cerr << "Failed to load XML file: " << filename << endl;
        return false;
    }

    XMLElement* root = doc.FirstChildElement("cross_effect");
    if (!root) {
        //cerr << "Root element 'cross_effect' not found!" << endl;
        return false;
    }

    pConfig->version = root->FloatAttribute("version", 1.0f);
    pConfig->enabled = root->BoolAttribute("enabled", false);

    // 解析 <delay> 元素
    if (XMLElement* delayElem = root->FirstChildElement("delay")) {
        pConfig->delay.duration = delayElem->IntAttribute("duration", 20);
        pConfig->delay.enabled = delayElem->BoolAttribute("enabled", false);

        if (XMLElement* exceptElem = delayElem->FirstChildElement("except")) {
            for (XMLElement* targetElem = exceptElem->FirstChildElement("target");
                 targetElem;
                 targetElem = targetElem->NextSiblingElement("target")) {
                pConfig->delay.exceptChannels.push_back(
                    targetElem->IntAttribute("channel", -1)
                );
            }
        }
    }

    // 解析 <remixes> 元素
    if (XMLElement* remixesElem = root->FirstChildElement("remixes")) {
        pConfig->remixes.enabled = remixesElem->BoolAttribute("enabled", false);

        // 解析 group 属性
        const char* groupAttr = remixesElem->Attribute("group");
        if (groupAttr) {
            pConfig->remixes.group = groupAttr;
        }

        // 解析 threshold 属性
        pConfig->remixes.threshold = remixesElem->FloatAttribute("threshold", 0.001f);

        if (pConfig->version >= 2.0f) {
            // 解析 v2.0 的 <group> 元素
            for (XMLElement* groupElem = remixesElem->FirstChildElement("group");
                 groupElem;
                 groupElem = groupElem->NextSiblingElement("group")) {
                Group group;
                const char* groupName = groupElem->Attribute("name");
                if (groupName) {
                    group.name = groupName;
                }
                for (XMLElement* remixElem = groupElem->FirstChildElement("remix");
                     remixElem;
                     remixElem = remixElem->NextSiblingElement("remix")) {
                    Remix remix;
                    if (parseRemixElement(remixElem, remix)) {
                        group.remixes.push_back(remix);
                    }
                }
                pConfig->remixes.groups.push_back(group);
            }
        } else {
            // 添加<group>元素，并解析 v1.0 的 <remix> 元素
            Group group;
            for (XMLElement* remixElem = remixesElem->FirstChildElement("remix");
                 remixElem;
                 remixElem = remixElem->NextSiblingElement("remix")) {
                Remix remix;
                if (parseRemixElement(remixElem, remix)) {
                    group.remixes.push_back(remix);
                }
            }
            pConfig->remixes.groups.push_back(group);
        }
    }

    return true;
}

void logCrossEffectConfig(CrossEffectConfig* pConfig) {
    ALOGV("CrossEffectConfig:");
    ALOGV("  Version: %f", pConfig->version);
    ALOGV("  Enabled: %s", pConfig->enabled ? "true" : "false");
    ALOGV("Delay:");
    ALOGV("  Enabled: %s", pConfig->delay.enabled ? "true" : "false");
    ALOGV("  Duration: %d ms", pConfig->delay.duration);
    string channels_str;
    for (int channel : pConfig->delay.exceptChannels) {
        channels_str += " " + std::to_string(channel);
    }
    ALOGV("  Except Channels:%s", channels_str.c_str());

    ALOGV("Remixes:");
    ALOGV("  Enabled: %s", pConfig->remixes.enabled ? "true" : "false");
    ALOGV("  Group: %s", pConfig->remixes.group.c_str());
    ALOGV("  Threshold: %f", pConfig->remixes.threshold);

    // 输出 v2 版本的 groups
    for (const Group& group : pConfig->remixes.groups) {
        ALOGV("  Group: %s", group.name.c_str());
        for (const Remix& remix : group.remixes) {
            ALOGV("    Remix:");
            ALOGV("      Sources:");
            for (const Channel& source : remix.sources) {
                ALOGV("        Channel: %d, Gain: %f, Factor: %f", source.channel, source.gain, source.factor);
            }
            ALOGV("      Target:");
            ALOGV("        Channel: %d, Gain: %f, Factor: %f", remix.target.channel, remix.target.gain, remix.target.factor);
        }
    }
}